home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / jcool01.zip / MATRIX.H < prev    next >
C/C++ Source or Header  |  1992-10-01  |  15KB  |  378 lines

  1. //
  2. // Copyright (C) 1991 Texas Instruments Incorporated.
  3. // Copyright (C) 1992 General Electric Company.
  4. //
  5. // Permission is granted to any individual or institution to use, copy, modify,
  6. // and distribute this software, provided that this complete copyright and
  7. // permission notice is maintained, intact, in all copies and supporting
  8. // documentation.
  9. //
  10. // Texas Instruments Incorporated, General Electric Company,
  11. // provides this software "as is" without express or implied warranty.
  12. //
  13. // Created: MBN 04/21/89 -- Initial design and implementation
  14. // Updated: MBN 06/22/89 -- Removed non-destructive methods
  15. // Updated: LGO 08/09/89 -- Inherit from Generic
  16. // Updated: MBN 08/20/89 -- Changed template usage to reflect new syntax
  17. // Updated: MBN 09/11/89 -- Added conditional exception handling and base class
  18. // Updated: LGO 10/05/89 -- Don't re-allocate data in operator= when same size
  19. // Updated: LGO 10/19/89 -- Add extra parameter to varargs constructor
  20. // Updated: MBN 10/19/89 -- Added optional argument to set_compare method
  21. // Updated: LGO 12/08/89 -- Allocate column data in one chunk
  22. // Updated: LGO 12/08/89 -- Clean-up get and put, add const everywhere.
  23. // Updated: LGO 12/19/89 -- Remove the map and reduce methods
  24. // Updated: MBN 02/22/90 -- Changed size arguments from int to unsigned int
  25. // Updated: MJF 06/30/90 -- Added base class name to constructor initializer
  26. // Updated: VDN 02/21/92 -- New lite version
  27. // Updated: VDN 05/05/92 -- Use envelope to avoid unecessary copying
  28. // Updated: JAM 08/24/92 -- removed DOS specifics, stdized #includes
  29. // Updated: JAM 08/24/92 -- modernized template syntax, remove macro hacks
  30. //                          non-template classes CoolMatrix=>CoolBase_Matrix
  31. // Updated: JAM 08/24/92 -- removed any reference to envelope classes
  32. // Updated: JAM 08/24/92 -- no default args for operators, so added extra op()
  33. // Updated: JAM 08/24/92 -- made put()'s value a 'const' Type&
  34. // Updated: JAM 09/26/92 -- put envelope back but using modern templates
  35. //
  36. // The parameterized Matrix<Type>  class is publicly   derived from the  Matrix
  37. // class and implements two dimensional arithmetic matrices of a user specified
  38. // type.   This is accompilshed by using  the parameterized  type capability of
  39. // C++.  The only constraint placed on the type  is  that it must  overload the
  40. // following operators: +, -,  *,  and /. Thus, it will  be possible to have  a
  41. // Matrix of  type Complex.  The Matrix<Type> class  is static in size, that is
  42. // once a  Matrix<Type> of  a particular  size has been   declared, there is no
  43. // dynamic growth or resize method available.
  44. //
  45. // Each matrix contains  a protected  data section  that has a  Type** slot  that
  46. // points to the  physical memory allocated  for the two  dimensional array. In
  47. // addition, two integers  specify   the number  of  rows  and columns  for the
  48. // matrix.  These values  are provided in the  constructors. A single protected
  49. // slot  contains a pointer  to a compare  function  to   be used  in  equality
  50. // operations. The default function used is the built-in == operator.
  51. //
  52. // Four  different constructors are provided.  The  first constructor takes two
  53. // integer arguments  specifying the  row  and column  size.   Enough memory is
  54. // allocated to hold row*column elements  of type Type.  The second constructor
  55. // takes the  same two  first arguments, but  also accepts  an additional third
  56. // argument that is  a reference to  an  object of  the appropriate  type whose
  57. // value is used as an initial fill value.  The third constructor is similar to
  58. // the third, except that it accpets a variable number of initialization values
  59. // for the Matrix.  If there are  fewer values than elements,  the rest are set
  60. // to zero. Finally, the last constructor takes a single argument consisting of
  61. // a reference to a Matrix and duplicates its size and element values.
  62. //
  63. // Methods   are  provided   for destructive   scalar   and Matrix    addition,
  64. // multiplication, check for equality  and inequality, fill, reduce, and access
  65. // and set individual elements.  Finally, both  the  input and output operators
  66. // are overloaded to allow for fomatted input and output of matrix elements.
  67.  
  68. #ifndef MATRIXH                    // If no Matrix class,
  69. #define MATRIXH                    // define it
  70.  
  71. #ifndef STDARGH
  72. #include <stdarg.h>                // for variable arglists
  73. #define STDARGH
  74. #endif
  75.  
  76. #ifndef BASE_MATRIXH                // If no base class definition
  77. #include <cool/Base_Matrix.h>            // include it
  78. #endif    
  79.  
  80. //## hack to workaround BC++ 3.1 Envelope bug
  81. #undef CoolEnvelope_H
  82. #define CoolEnvelope CoolEnvelope_Matrix
  83.  
  84. template<class CoolLetter> class CoolEnvelope;
  85.  
  86. template<class Type>
  87. class CoolMatrix : public CoolBase_Matrix {
  88. public:
  89.   typedef Boolean (*Compare)(const Type&, const Type&);
  90.  
  91.   CoolMatrix(unsigned int r=1, unsigned int c=1); // m (r,c);
  92.   CoolMatrix(unsigned int r, unsigned int c, const Type& v0); // m(r,c,init);
  93.   CoolMatrix(unsigned int r, unsigned int c, int n, 
  94.             Type v00, ...); 
  95.   CoolMatrix(unsigned int r, unsigned int c, // from a block of data
  96.             const Type* data_block);        // stored row-wise.
  97.  
  98.   CoolMatrix(const CoolMatrix<Type>&);    // m1 = m2;
  99.   ~CoolMatrix();                // Destructor
  100.   
  101.   inline void put (unsigned int r, unsigned int, const Type&); // Assign value
  102.   inline Type& get (unsigned int r, unsigned int);       // Get value
  103.   void fill (const Type&);                   // Set elements to value
  104.   
  105.   inline Type& operator() (unsigned int r, unsigned int c); // Access wo checks
  106.   inline Type& operator() (unsigned int r) { return (*this)(r,0); }
  107.   
  108.   CoolMatrix<Type>& operator= (const Type&);    // Assignment: m = 2;
  109.   CoolMatrix<Type>& operator= (const CoolMatrix<Type>&); // Assignment: m = n;
  110.   inline CoolMatrix<Type>& operator= (CoolEnvelope< CoolMatrix<Type> >&); 
  111.   
  112.   Boolean operator== (const CoolMatrix<Type>&) const; // CoolMatrix equality test
  113.   inline Boolean operator!= (const CoolMatrix<Type>&) const; // inequality test
  114.   void set_compare (Compare = NULL);         // Compare function
  115.   
  116.   friend ostream& operator<< (ostream&, const CoolMatrix<Type>&);
  117.   /*inline##*/ friend ostream& operator<< (ostream&, const CoolMatrix<Type>*);
  118.   
  119.   CoolMatrix<Type>& operator+= (const Type&);    // binary operation and assignment
  120.   CoolMatrix<Type>& operator*= (const Type&);    // Mutate matrix data
  121.   CoolMatrix<Type>& operator/= (const Type&);
  122.   inline CoolMatrix<Type>& operator-= (const Type&);    
  123.   
  124.   CoolMatrix<Type>& operator+= (const CoolMatrix<Type>&);
  125.   CoolMatrix<Type>& operator-= (const CoolMatrix<Type>&);
  126.   inline CoolMatrix<Type>& operator*= (const CoolMatrix<Type>&);
  127.   
  128.   CoolEnvelope< CoolMatrix<Type> > operator- () const;        // negation and 
  129.   CoolEnvelope< CoolMatrix<Type> > operator+ (const Type&) const; // all binary operations 
  130.   CoolEnvelope< CoolMatrix<Type> > operator* (const Type&) const; // return by values.
  131.   CoolEnvelope< CoolMatrix<Type> > operator/ (const Type&) const;
  132.   
  133.   inline CoolEnvelope< CoolMatrix<Type> > operator- (const Type&) const; 
  134.   /*inline##*/ friend CoolEnvelope< CoolMatrix<Type> > operator+ (const Type&, const CoolMatrix<Type>&);
  135.   /*inline##*/ friend CoolEnvelope< CoolMatrix<Type> > operator- (const Type&, const CoolMatrix<Type>&);
  136.   /*inline##*/ friend CoolEnvelope< CoolMatrix<Type> > operator* (const Type&, const CoolMatrix<Type>&);
  137.   
  138. // Fewer unnecessary copying with CoolEnvelope
  139. //  friend CoolMatrix<Type> operator+ (const CoolMatrix<Type>&, 
  140. //                       const CoolMatrix<Type>&);
  141. //  friend CoolMatrix<Type> operator- (const CoolMatrix<Type>&, 
  142. //                       const CoolMatrix<Type>&);
  143.   friend CoolEnvelope< CoolMatrix<Type> > operator* (const CoolMatrix<Type>&, 
  144.                       const CoolMatrix<Type>&);
  145.   
  146.   ////--------------------------- Additions ------------------------------------
  147.   
  148.   CoolEnvelope< CoolMatrix<Type> > transpose () const;        // transpose row/column
  149.   
  150.   CoolEnvelope< CoolMatrix<Type> > abs () const;        // absolute of all elements
  151.   CoolEnvelope< CoolMatrix<Type> > sign () const;
  152.   CoolEnvelope< CoolMatrix<Type> > extract (unsigned int rows, unsigned int cols, // get submatrix
  153.                 unsigned int top=0, unsigned int left=0) const;
  154.   CoolMatrix<Type>& update (const CoolMatrix<Type>&, // update submatrix
  155.                 unsigned int top=0, unsigned int left=0);         
  156.   
  157.   friend CoolEnvelope< CoolMatrix<Type> > element_product (const CoolMatrix<Type>&, // a[ij]*b[ij]
  158.                        const CoolMatrix<Type>&);
  159.   friend CoolEnvelope< CoolMatrix<Type> > element_quotient (const CoolMatrix<Type>&, // a[ij]/b[ij]
  160.                         const CoolMatrix<Type>&);
  161.   Type determinant() const;            // determinant of square matrix
  162.  
  163.   
  164.   ////--------------------------- Vector ---------------------------------------
  165.   
  166.   inline Type& x ();                // using a 2d matrix
  167.   inline Type& y ();                // to represent a 1d vector
  168.   inline Type& z ();                // is less efficient 
  169.   inline Type& t ();                // in time and space
  170.   
  171.   friend Type dot_product (const CoolMatrix<Type>&, // dot-product of n-dim vectors
  172.                const CoolMatrix<Type>&); 
  173.   friend Type cross_2d (const CoolMatrix<Type>&, // cross-product of 2d-vectors
  174.             const CoolMatrix<Type>&);
  175.   friend CoolEnvelope< CoolMatrix<Type> > cross_3d (const CoolMatrix<Type>&, // cross-product 
  176.                     const CoolMatrix<Type>&); // of 3d-vectors 
  177.  
  178.   inline const Type* data_block ();        // block of data, row-major order.
  179.  
  180. protected:
  181.   Type** data;                    // Pointer to the CoolMatrix 
  182.   static Boolean (*compare_s)(const Type&, const Type&);    // Pointer operator== function
  183.   friend Boolean CoolMatrix_is_data_equal (const Type&, const Type&);
  184. };
  185.  
  186.  
  187. //## BC++ 3.1 bug
  188. void hack(CoolMatrix<int>);
  189. void hack(CoolMatrix<float>);
  190. void hack(CoolMatrix<double>);
  191. //## add your type above
  192. #include <cool/Envelope.h>    //## BC++ 3.1 bug prevents from moving to top
  193.  
  194. // Use envelope to avoid deep copy on return by value, and mutate in place
  195. template<class Type>
  196. inline CoolEnvelope< CoolMatrix<Type> > operator+ (const CoolMatrix<Type>&arg1,const CoolMatrix<Type>&arg2)
  197.    { return CoolEnvOp(add)(arg1, arg2); }
  198. template<class Type>
  199. inline CoolEnvelope< CoolMatrix<Type> > operator- (const CoolMatrix<Type>&arg1,const CoolMatrix<Type>&arg2)
  200.    { return CoolEnvOp(minus)(arg1, arg2); }
  201.  
  202.  
  203. // get -- Get the element at specified index and return value
  204. // Input: this*, row, column
  205. // Output: Element value
  206.  
  207. template<class Type> 
  208. inline Type& CoolMatrix<Type>::get (unsigned int row, unsigned int column) {
  209. #if ERROR_CHECKING
  210.   if (row >= this->num_rows)            // If invalid size specified
  211.     this->row_index_error ("get", #Type, row);    // Raise exception
  212.   if (column >= this->num_cols)            // If invalid size specified
  213.     this->col_index_error ("get", #Type, column); // Raise exception
  214. #endif
  215.   return this->data[row][column];
  216. }
  217.  
  218. // put -- Put the element value at specified index
  219. // Input: *this, row, column, value
  220. // Output: Element value
  221.  
  222. template<class Type> 
  223. inline void CoolMatrix<Type>::put (unsigned int row, unsigned int column, const Type& value) {
  224. #if ERROR_CHECKING
  225.   if (row >= this->num_rows)            // If invalid size specified
  226.     this->row_index_error ("put", #Type, row);    // Raise exception
  227.   if (column >= this->num_cols)            // If invalid size specified
  228.     this->col_index_error ("put", #Type, column); // Raise exception
  229. #endif
  230.   this->data[row][column] = value;        // Assign data value
  231. }
  232.  
  233. // operator() -- Overload () to get the element at specified index
  234. //               and return by reference
  235. // Input: this*, row, column
  236. // Output: Element value
  237.  
  238. template<class Type> 
  239. inline Type& CoolMatrix<Type>::operator() (unsigned int row, unsigned int column) {
  240.   return this->data[row][column];        // fast access without checks.
  241. }
  242.  
  243.  
  244. // operator=  -- Assignment from an envelope back to real matrix
  245. // Input:     envelope reference
  246. // Output:    matrix reference with contents in envelope being swapped over
  247.  
  248. template<class Type>
  249. inline CoolMatrix<Type>& CoolMatrix<Type>::operator= (CoolEnvelope< CoolMatrix<Type> >& env){
  250.   env.shallow_swap((CoolEnvelope< CoolMatrix<Type> >*)this, &env); // same physical layout
  251.   return *this;
  252. }
  253.  
  254. // operator<< -- Overload the output operator to print a CoolMatrix
  255. // Input:        ostream reference, CoolMatrix pointer
  256. // Output:       ostream reference
  257.  
  258. template<class Type>
  259. inline ostream& operator<< (ostream& os, const CoolMatrix<Type>* m) {
  260.   if (m) os << *m;
  261.   return os;
  262. }
  263.  
  264.  
  265. // operator!= -- Perform not equal comparison test
  266. // Input:        this*, matrix reference
  267. // Output:       TRUE/FALSE
  268.  
  269. template<class Type> 
  270. inline Boolean CoolMatrix<Type>::operator!= (const CoolMatrix<Type>& m) const {
  271.   return (!operator== (m));
  272. }
  273.  
  274. // operator-= -- Destructive matrix subtraction of a scalar.
  275. // Input:        this*, scalar value
  276. // Output:       New matrix reference
  277.  
  278. template<class Type> 
  279. inline CoolMatrix<Type>& CoolMatrix<Type>::operator-= (const Type& value) {
  280.   return *this += (- value);
  281. }
  282.  
  283.  
  284. template<class Type>
  285. inline CoolEnvelope< CoolMatrix<Type> > operator+ (const Type& value,
  286.                     const CoolMatrix<Type>& m) {
  287.   return m + value;
  288. }
  289.  
  290. // operator- -- Non-destructive matrix substraction of a scalar.
  291. // Input:       this*, scalar value
  292. // Output:      New matrix 
  293.  
  294. template<class Type> 
  295. inline CoolEnvelope< CoolMatrix<Type> > CoolMatrix<Type>::operator-(const Type& value) const {
  296.   return (*this) + (- value);
  297. }
  298.  
  299. template<class Type>
  300. inline CoolEnvelope< CoolMatrix<Type> > operator- (const Type& value,
  301.                     const CoolMatrix<Type>& m) {
  302.   return (- m) + value;
  303. }
  304.  
  305.  
  306. template<class Type>
  307. inline CoolEnvelope< CoolMatrix<Type> > operator* (const Type& value,
  308.                     const CoolMatrix<Type>& m) {
  309.   return m * value;
  310. }
  311.  
  312. template<class Type>
  313. inline CoolMatrix<Type>& CoolMatrix<Type>::operator*= (const CoolMatrix<Type>&m) {
  314.   *this = (*this) * m;                // multiply, then shallow swap
  315.   return *this;
  316. }
  317.  
  318. ////--------------------------  Vector ----------------------------------
  319. //// use a column matrix to represent 1d vector
  320.  
  321. template<class Type>                
  322. inline Type& CoolMatrix<Type>::x(){
  323.   return data[0][0];
  324. }        
  325.  
  326. template<class Type>
  327. inline Type& CoolMatrix<Type>::y() {
  328.   return data[1][0];
  329. }
  330.  
  331. template<class Type>
  332. inline Type& CoolMatrix<Type>::z() {
  333.   return data[2][0];
  334. }        
  335.  
  336. template<class Type>
  337. inline Type& CoolMatrix<Type>::t() {
  338.   return data[3][0];
  339. }    
  340.  
  341.  
  342. // template<class Type>                // use a row matrix to
  343. // inline Type& CoolMatrix<Type>::x() {            // represent 1d vector
  344. //   return data[0][0];
  345. // }        
  346. // 
  347. // template<class Type>
  348. // inline Type& CoolMatrix<Type>::y() {
  349. //   return data[0][1];
  350. // }
  351. // 
  352. // template<class Type>
  353. // inline Type& CoolMatrix<Type>::z() {
  354. //   return data[0][2];
  355. // }        
  356. // 
  357. // template<class Type>
  358. // inline Type& CoolMatrix<Type>::t() {
  359. //   return data[0][3];
  360. // }    
  361.  
  362. // data_block -- Provide access to the contiguous block storing 
  363. //               the elements in the matrix row-wise.
  364. //               Use this only to cast matrix contents,
  365. //               to C array like: Type [rows][columns].
  366.  
  367. template<class Type>
  368. inline const Type* CoolMatrix<Type>::data_block () {
  369.   return data[0];                // start of array of data
  370. }
  371.  
  372. //## hack to workaround BC++ 3.1 Envelope bug
  373. #undef CoolEnvelope
  374.  
  375. #endif                        // End of MATRIXH
  376.  
  377.  
  378.